/****************************************************************************************
	Set Bitmap Parameters 1.4
	
	By Ofer Zelichover (c) 10/2001 
	scripts@oferz.com  www.oferz.com
	Last Modified: 3:46 AM Thursday, April 26, 2007
----------------------------------------------------------------------------------------	

This script comes with no waranty!
Although I tried ths script and couldn't find any problems with it, I can in no way be 
held responsible for any kind of loss or damage, whether direct or indirect, due  to the 
use of this script.

----------------------------------------------------------------------------------------

Description:
-------------
 Changes the bitmap parameters of all materials, selected objects' materials or material 
 editor materials.

*****************************************************************************************/

try(destroyDialog ro_SetBitmapParameters) catch()

rollout ro_SetBitmapParameters "Set Bitmap Parameters v1.4"
(
-- Local Struct Definitions
--------------------------------
	struct s_undoBuffer (
		controller, 
		property=#filename, 
		value="",
		
		fn restoreValue = 
		(
--			if controller != undefined and isProperty controller property then
				setProperty controller property value
		)
	)


-- Local Variables Declerations
--------------------------------
	local objs = sceneMaterials
	local mapsCounter = 0
	local objsCounter = 0
	local undoBuffer = #()


-- GUI
--------
	group "Materials to process: " (
		radiobuttons objsToProc "" labels:#("All Scene Materials","Selected Objects Materials", "Material Editor Materials") columns:1 align:#left
	)
	group "Bitmap filtering: " (
		checkbox FilterTypeCB "Don't change" offset:[0,-5] checked:true
		radiobuttons filterType "" labels:#("Pyramidal", "Summed Area", "None") columns:1 align:#left offset:[15,0] enabled:false
	)
	group "Bitmap file name: " (
		checkbox cbFileName "Don't change" offset:[0,-5] checked:true
		checkbox cbFileNameStripPath "Strip file name from path" offset:[15,0] checked:false enabled:false
		label fileNameLbl_01 "Replace file name:" enabled:false align:#left offset:[15,0]
		edittext fileNameReplace "" fieldWidth:215 align:#center enabled:false offset:[5,0]
		label fileNameLbl_02 "With (file name):" enabled:false align:#left offset:[15,0]
		edittext fileNameWith "" fieldWidth:215 align:#center enabled:false offset:[5,0]
		label fileNameLbl_03 "* Wildcards allowed" enabled:false align:#left
		label fileNameLbl_04 "* Use \"-none-\" to match empty bitmaps" enabled:false align:#left
	)
	group "Status: " (
		label processed "Materials processed:" align:#left
		label contCount "Maps changed:" align:#left
		progressBar progBar offset:[0,5]
	)
	button bnGo "Execute" width:60 pos:[5,(ro_SetBitmapParameters.height-25)] 
	button bnUndo "Undo" width:45 pos:(bnGo.pos + [70,0]) enabled:(undoBuffer.count > 0)
	button bnAbout "About" width:45 pos:(bnUndo.pos + [70,0])
	button bnClose "Close" width:45 pos:(bnAbout.pos + [55,0])
	
-- Functions
-------------
	fn validFilename fName = (
		true
	)

	fn replaceFilename fName sourcePat destPat = (
		destPatQM = findString destPat "?"
		destPatAst = findString destPat "*"
		if destPatQM == undefined and destPatAst == undefined then
			return destPat
		try (
			local sourceArr = filterString sourcePat "*?"
			local wildCardArr = #()
			local tmpStr = copy fName
			if sourcePat[1] == "*" OR sourcePat[1] == "?" then (
				local s = try(subString fName 1 ((findString fName sourceArr[1])-1))catch("")
				append wildCardArr s
			)
	
			for i = 1 to (sourceArr.count-1) do (
				local n1 = (findString tmpStr sourceArr[i])+sourceArr[1].count
				local n2 = findString tmpStr sourceArr[i+1]
				local s = subString tmpStr n1 (n2-n1)
				append wildCardArr s
				tmpStr = subString tmpStr n1 (tmpStr.count-n1)
			)
	
			if sourcePat[sourcePat.count] == "*" OR sourcePat[sourcePat.count] == "?" then (
				local n = (findString fName sourceArr[sourceArr.count]) + sourceArr[sourceArr.count].count
				local s = try(subString fName n sourcePat.count)catch("")
				append wildCardArr s
			)
			
			local _fName = ""
			local n = 1
			for i = 1 to destPat.count do (
				case destPat[i] of (
					"*": (_fName += wildCardArr[n]; n+=1)
					"?": (_fName += wildCardArr[n]; n+=1)
					default: _fName += destPat[i]
				)
			)
		)catch(_fName = fName)
		_fName
	)

	fn recurseSubAnims subA = (
		if subA != undefined then (
			local incUpdateCounter = false
			if isKindOf subA SubAnim AND isKindOf subA.object Bitmaptexture then (
				if NOT filterTypeCB.state then (
					append undoBuffer (s_UndoBuffer subA.object property:#filtering value:subA.filtering)
					subA.filtering = filterType.state-1
					incUpdateCounter = true
				)
				if NOT cbFileName.state then (
					local origVal = (subA.filename as string)
					local createUndo = false
					local isEmptyFilename = (matchPattern fileNameReplace.text pattern:"-none-") and (subA.filename == "")
					if (fileNameReplace.text != "") and (isEmptyFilename or (matchPattern (subA.filename as string) pattern:fileNameReplace.text)) then (
						if isEmptyFilename then
							subA.filename = fileNameWith.text
						else
							subA.filename = replaceFilename subA.filename fileNameReplace.text fileNameWith.text
						incUpdateCounter = true
						createUndo = true
					)
					if cbFileNameStripPath.state then (
						subA.filename = filenameFromPath subA.filename
						incUpdateCounter = true
						createUndo = true
					)
					append undoBuffer (s_UndoBuffer subA.object property:#filename value:origVal)
				)
			)
			if incUpdateCounter then (
				mapsCounter += 1
				contCount.text =  ("Maps changed: " + mapsCounter as string)
			)
			for i = 1 to subA.numSubs do (
				recurseSubAnims subA[i]
			)
		) else
			undefined
	)
	
	fn updateObjs = (
		case objsToProc.state of (
			1: objs = sceneMaterials
			2: objs = for o in selection where (o.material!=undefined) collect o.material
			3: objs = meditMaterials
		)
	)

	fn aboutWin = (
		local txt = ""
		txt += "Set Bitmap Parameters\n"
		txt += "By Ofer Zelichover\n"
		txt += "(www.oferz.com ; scripts@oferz.com)\n\n"
		txt += "Description: Batch change of bitmap parameters.\n\n"
		txt += "If you find any bugs, please let me know\n\n"
		txt += "This script comes with no waranty!\n"
		txt += "Although I tried ths script and couldn't find any problems with it,\n"
		txt += "I can in no way be held responsible for any kind of loss or damage,\n"
		txt += "whether direct or indirect, due  to the use of this script."
		messagebox txt title:"About Set Bitmap Parameters"
	)
	
-- Event Handlers
-------------------
	on FilterTypeCB changed state do (filterType.enabled = NOT state)

	on cbFileName changed state do (
		cbFileNameStripPath.enabled = NOT state
		fileNameReplace.enabled = NOT state
		fileNameWith.enabled = NOT state
		fileNameLbl_01.enabled = NOT state
		fileNameLbl_02.enabled = NOT state
		fileNameLbl_03.enabled = NOT state
	)
	
	on bnAbout pressed do aboutWin()
	
	on bnGo pressed do (
		undoBuffer = #()
		if fileNameReplace.text!="" and fileNameWith.text=="" then
			if NOT (queryBox "You didn't enter anything in the \"Replae with\" field.\nThis will remove the file from the bitmaps whose names match the \"Replace\" field.\n Continue execute anyway?" title:"Warning") then
				return undefined
		updateObjs()
		n = 0
		mapsCounter = 0
		objsCounter = 0
		progBar.value = 0
		contCount.text =  ("Maps changed: " + mapsCounter as string)
		local cnt = objs.count as float
		local cntStr = objs.count as string
		for o in objs do (
			n+=1
			processed.text = ("Materials processed: "+n as string+" / "+cntStr)
			progBar.value = (100.*n/cnt) as integer
			recurseSubAnims o
		)
		bnUndo.enabled = (undoBuffer.count > 0)
	)
	
	on bnUndo pressed do (
		local cnt = undoBuffer.count
		local cntStr = undoBuffer.count as string
		progBar.value = 0
		for i = 1 to cnt do (
			undoBuffer[i].restoreValue()
			processed.text = ("Materials processed: "+i as string+" / "+cntStr)
			progBar.value = ((i / cnt as float) * 100.) as integer
		)
		undoBuffer  = #()
		bnUndo.enabled = (undoBuffer.count > 0)
	)
	
	on bnClose pressed do (destroyDialog ro_SetBitmapParameters; gc())
) -- end setWireRanges rollout

createDialog ro_SetBitmapParameters 250 460

